package com.gr.staffpm.pages.projects;

import java.text.SimpleDateFormat;
import java.util.List;

import org.apache.shiro.SecurityUtils;
import org.apache.wicket.PageParameters;
import org.apache.wicket.extensions.markup.html.repeater.data.sort.OrderByBorder;
import org.apache.wicket.markup.html.basic.Label;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.markup.repeater.Item;
import org.apache.wicket.markup.repeater.data.DataView;
import org.apache.wicket.model.PropertyModel;
import org.apache.wicket.spring.injection.annot.SpringBean;
import org.joda.time.DateTime;

import com.gr.staffpm.charts.FlotPanel;
import com.gr.staffpm.charts.FlotUtils;
import com.gr.staffpm.charts.PredefinedCharts;
import com.gr.staffpm.charts.Series;
import com.gr.staffpm.datatypes.Project;
import com.gr.staffpm.datatypes.Task;
import com.gr.staffpm.datatypes.User;
import com.gr.staffpm.pages.tasks.ViewTask;
import com.gr.staffpm.projects.service.ProjectService;
import com.gr.staffpm.security.constants.StaffPMRoles;
import com.gr.staffpm.security.service.UserService;
import com.gr.staffpm.tasks.service.SortableTaskDataProvider;


public class SummaryTabPanel extends Panel {

    @SpringBean(name = "userService")
    private UserService userService;
    @SpringBean(name = "projectService")
    private ProjectService projectService;
    private final Project project;
    private static final long serialVersionUID = 1L;

    /**
     * Constructor
     * 
     * @param id the component id
     * @param p the {@link Project} to which we are viewing
     */
    public SummaryTabPanel(String id, Project p) {
        super(id);

        this.project = p;
        final SimpleDateFormat date = new SimpleDateFormat("dd MMM yyyy");

        //Summary Module
        add(new Label("projectKey", p.getKey()));
        add(new Label("projectLead", p.getOwner().getFirstName() + " " + p.getOwner().getLastName()));
        add(new Label("projectStart", date.format(p.getStartDate())));
        add(new Label("projectDesc", p.getDescription()));

        //Tasks Due Module
        SortableTaskDataProvider dp = new SortableTaskDataProvider(projectService, project);
        dp.setSort(Task.DUE_DATE, true);
        final DataView<Task> dueView = new DataView<Task>("tasksDue", dp) {

            private static final long serialVersionUID = 1L;

            @Override
            protected void populateItem(Item<Task> item) {
                final Task task = item.getModelObject();

                Link<Task> taskLink = new Link<Task>("taskLink", item.getModel()) {

                    private static final long serialVersionUID = 1L;

                    @Override
                    public void onClick() {
                        User currUser = userService.getCurrentUser();
                        boolean owner = currUser.equals(task.getAssignee()) || currUser.equals(task.getCreatedBy());
                        boolean admin = SecurityUtils.getSubject().hasRole(StaffPMRoles.ADMIN);
                        boolean readable =
                                SecurityUtils.getSubject().isPermitted("project:readtasks:" + task.getProject().getProjectId())
                                        || SecurityUtils.getSubject().isPermitted("task:read:" + task.getTaskId());
                        if (readable || admin || owner) {
                            setResponsePage(new ViewTask(new PageParameters("id=" + String.valueOf(task.getTaskId()))));
                        } else
                            error("You do not have permission to view task: " + task.getName());
                    }

                };

                item.add(taskLink.add(new Label("name", task.getName())));
                item.add(new Label("due", date.format(task.getDueDate())));
            }
        };
        dueView.setItemsPerPage(5);

        add(new OrderByBorder("orderByTaskName", Task.NAME, dp));
        add(new OrderByBorder("orderByDueDate", Task.DUE_DATE, dp));

        add(dueView);

        FlotPanel panel = new FlotPanel("chart", new PropertyModel<List<Series>>(this, "data"));
        panel.setAxisTicksX(FlotUtils.getTicksForWeeksBetween(new DateTime().withTime(0, 0, 0, 0).minusDays(30), 5));
        panel.setAxisTimeModeX(true);
        panel.setAxisMinX(new DateTime().withTime(0, 0, 0, 0).minusDays(30));
        panel.setAxisMaxX(new DateTime().withTime(0, 0, 0, 0));
        panel.setAxisMinY(0.0);
        panel.setAxisMinTimeTickSizeX(1, "month");
        panel.setPointsVisible(true);
        add(panel);

        //Tasks Updated Module
        SortableTaskDataProvider updated = new SortableTaskDataProvider(projectService, project);
        updated.setSort(Task.LAST_UPDATED, false);
        final DataView<Task> updatedView = new DataView<Task>("tasksUpdated", updated) {

            private static final long serialVersionUID = 1L;

            @Override
            protected void populateItem(Item<Task> item) {
                final Task task = item.getModelObject();

                Link<Task> taskLink = new Link<Task>("taskLink", item.getModel()) {

                    private static final long serialVersionUID = 1L;

                    @Override
                    public void onClick() {
                        setResponsePage(new ViewTask(new PageParameters("id=" + String.valueOf(task.getTaskId()))));
                    }

                };

                item.add(taskLink.add(new Label("name", task.getName())));
                item.add(new Label("updated", date.format(task.getLastUpdated())));
            }
        };
        updatedView.setItemsPerPage(5);

        add(new OrderByBorder("orderByTaskName2", Task.NAME, updated));
        add(new OrderByBorder("orderByUpdatedDate", Task.LAST_UPDATED, updated));

        add(updatedView);
    }

    public List<Series> getData() {

        DateTime date = new DateTime().withTime(0, 0, 0, 0).minusDays(30);
        List<Task> tasksCreated = projectService.getTasksCreated(project, date.toDate(), new DateTime().toDate());
        List<Task> tasksResolved = projectService.getTasksResolved(project, date.toDate(), new DateTime().toDate());

        return PredefinedCharts.createdVsResolvedChart(tasksCreated, tasksResolved, 30);
    }

}
